package ru.amse.baltijsky.javascheme.util;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.util.Random;

public final class Util {
    private static Random randomGenerator = new Random();

    public static <T extends Comparable<T>> T max(T t1, T t2) {
        return t1.compareTo(t2) > 0 ? t1 : t2;
    }

    public static <T extends Comparable<T>> T min(T t1, T t2) {
        return t1.compareTo(t2) < 0 ? t1 : t2;
    }

    public static boolean equalIgnoreWhitespace(String s1, String s2) {
        String whiteCharacterRegex = "[ \\t\\n\\x0B\\f\\r]";
        return s1.replaceAll(whiteCharacterRegex, "").equals(s2.replaceAll(whiteCharacterRegex, ""));
    }

    public static <E extends Enum<E>> E getEnumValue(String name, Iterable<E> values) {
        for (E e : values) {
            if (name.equalsIgnoreCase(e.name())) {
                return e;
            }
        }
        throw new IllegalArgumentException("Enum value" + name + " not found.");
    }

    /**
     * Returns random integer value in the range [0 .. max - 1].
     *
     * @param max amount of possible results
     * @return random integer value in the range [0 .. max - 1]
     */
    public static int random(int max) {
//        return (int) Math.floor(max * Math.random());
        return randomGenerator.nextInt(max > 0 ? max : 1);
    }

    /**
     * Returns random boolean value.
     *
     * @return random boolean value
     */
    public static boolean randomBool() {
//        return random(1) == 1;
        return randomGenerator.nextBoolean();
    }

    /**
     * Calculates the amount of digits in the number (decimal base).
     */
    public static int nDigits(int n) {
        int count = 0;
        for (int k = n; k > 0; k /= 10, ++count) ;
        return count;
    }

    /**
     * Searches for file in the class path given the file name, returns it if found, throws FNFE otherwise.
     *
     * @param fileName the name of the file to search for
     * @return the found file
     * @throws FileNotFoundException if the file was not found
     */
    public static File findFile(final String fileName) throws FileNotFoundException {
        String classPath = System.getProperty("java.class.path");
        String[] strSearchRoots = classPath.split(";");
        File[] fileSearchRoots = new File[strSearchRoots.length];
        for (int i = 0; i < strSearchRoots.length; ++i) {
            fileSearchRoots[i] = new File(strSearchRoots[i]);
        }
        for (File f : fileSearchRoots) {
            if (!f.isDirectory()) {
                continue;
            }
            File found = scan(f, new FilenameFilter() {
                public boolean accept(File dir, String name) {
                    return new File(dir, name).isDirectory() || name.equals(fileName);
                }
            });
            if (found != null) {
                return found;
            }
        }
        throw new FileNotFoundException("could not find the file specified");
    }

    private static File scan(File path, FilenameFilter filter) {
        File[] files = path.listFiles(filter);
        for (File f : files) {
            if (f.isDirectory()) {
                File found = scan(f, filter);
                if (found != null) {
                    return found;
                }
            } else {
                // the name is right
                return f;
            }

        }
        return null;
    }

    public static String getExtension(File f) {
        String ext = "";
        String s = f.getName();
        int i = s.lastIndexOf('.');
        if (i > 0 && i < s.length() - 1) {
            ext = s.substring(i + 1).toLowerCase();
        }
        return ext;
    }
}
